/*
 * Created by Jaren at 2021/11/29 8:56
 */
import 'dart:typed_data';

import 'package:inmotion_protocol/common/product_version.dart';
import 'package:inmotion_protocol/common/vehicle_info.dart';
import 'package:inmotion_protocol/lorin/constant.dart';
import 'package:inmotion_protocol/lorin/factory/special/euc/euc_message_factory.dart';
import 'package:inmotion_protocol/lorin/lorin_message.dart';
import 'package:inmotion_protocol/util/byte_util.dart';
import 'package:inmotion_protocol/util/version.dart';

class V12MessageFactory extends EucLorinSpecialMessageFactory<_V12Cmd> {
  V12MessageFactory(ProductProperty productProperty) : super(productProperty);

  @override
  void initCompact(int apiVersion, VersionWrapper version) {
    compact = null;
    if (productProperty.model.isV12()) {
      if (VersionUtils.lower(
          version.getAppVersionByDevice(Constant.deviceEUCV12HMIC),
          VersionConstant.v12Hmic1424)) {
        // 仅 V12(020701) 型号，且人机板低于1.4.24以下才使用 V1 版本
        compact = _V12CmdV1();
      }
    }

    // 默认用V2 CMD
    compact ??= _V12CmdV2();
  }

  /// 开关前照明灯(近光灯和远光灯)
  /// 必须同时指定近光灯[lowBeamOn]和远关灯[highBeamOn]的状态
  @override
  LorinMessage genHeadlightOnOffMsg(
      {bool? on, bool? lowBeamOn, bool? highBeamOn, int? source, int? target}) {
    if (lowBeamOn == null || highBeamOn == null)
      throw Exception(
          'Low beam and high beam state should be set in the same time in V12.');
    Uint8ClampedList bytes = Uint8ClampedList(2);
    bytes[0] = lowBeamOn ? 1 : 0;
    bytes[1] = highBeamOn ? 1 : 0;
    return genSpecialOne2OneWriteMsg(compact!.headlightOnOffCmd(), bytes);
  }

  LorinMessage genAutoScreenOffOnOffMsg(bool on) {
    return genSpecialOne2OneWriteMsg(
        compact!.autoScreenOffCmd(), ByteUtil.bool2Bytes(on));
  }

  LorinMessage genAutoLowHighBeamOnOffMsg(bool on) {
    return genSpecialOne2OneWriteMsg(
        compact!.autoLowHighBeamOnOffCmd(), ByteUtil.bool2Bytes(on));
  }

  LorinMessage genSetAutoLowHighBeamSwitchSpeedThrMsg(int speedThr) {
    return genSpecialOne2OneWriteMsg(compact!.speedThrOfLowHighBeamSwitchCmd(),
        ByteUtil.num2BytesLe(speedThr, 2));
  }

  @override
  LorinMessage genSetLightEffectModeMsg(int mode,
      [Uint8ClampedList? param, int? source, int? target]) {
    if (param == null)
      throw Exception(
          "Param [param] for 'genSetLightEffectModeMsg' must be set in V12.");
    return genSpecialOne2OneWriteMsg(compact!.lightEffectModeCmd(),
        ByteUtil.buildBytes(ByteUtil.num2BytesLe(mode, 1), param));
  }

  LorinMessage genRequestLightEffectMsg() {
    return genSpecialOne2OneReadMsg(compact!.lightEffectModeCmd());
  }

  LorinMessage genRequestCurrentLightEffectIdMsg() {
    return genSpecialOne2OneReadMsg(compact!.lightEffectIdCmd());
  }

  LorinMessage genDisableChargeDangerAlertMsg() {
    return genSpecialOne2OneWriteMsg(
        compact!.disableChargeDangerAlertCmd(), Uint8ClampedList.fromList([1]));
  }

  LorinMessage genSetWarningLimitSpeedMsg(int speed1, int speed2) {
    Uint8ClampedList param = Uint8ClampedList(4);
    ByteUtil.num2BytesLe(speed1, 2, param, 0);
    ByteUtil.num2BytesLe(speed2, 2, param, 2);
    return genSpecialOne2OneWriteMsg(compact!.warningLimitSpeedCmd(), param);
  }
}

abstract class _V12Cmd extends EucCmdCompact {
  int autoLowHighBeamOnOffCmd();

  int autoScreenOffCmd();

  int speedThrOfLowHighBeamSwitchCmd();

  int disableChargeDangerAlertCmd() {
    return 0;
  }

  int warningLimitSpeedCmd() {
    return 62;
  }

  @override
  int bermAngleModeCmd() {
    return 0;
  }
}

class _V12CmdV1 extends _V12Cmd {
  @override
  int autoHeadlightCmd() {
    return 47;
  }

  @override
  int autoScreenOffCmd() {
    return 61;
  }

  @override
  int autoHeadlightBrightnessThrCmd() {
    return 42;
  }

  @override
  int brightnessOfHeadlightCmd() {
    return 43;
  }

  @override
  int calibrateImuCmd() {
    return 66;
  }

  @override
  int deviceNameCmd() {
    return 12;
  }

  @override
  int headlightOnOffCmd() {
    return 64;
  }

  @override
  int lightEffectIdCmd() {
    return 45;
  }

  @override
  int passwordCmd() {
    return 10;
  }

  @override
  int passwordTypeCmd() {
    return 11;
  }

  @override
  int remainderRangeEstimateCmd() {
    return 63;
  }

  @override
  int assistBalanceCmd() {
    return 0;
  }

  @override
  int soundWaveCmd() {
    return 57;
  }

  @override
  int soundWaveSensitivityCmd() {
    return 56;
  }

  @override
  int speedThrOfLowHighBeamSwitchCmd() {
    return 0;
  }

  @override
  int speedingBrakingCmd() {
    return 0;
  }

  @override
  int speedingBrakingSensitivityCmd() {
    return 0;
  }

  @override
  int transportationModeCmd() {
    return 50;
  }

  @override
  int usbPowerCmd() {
    return 60;
  }

  @override
  int lightEffectModeCmd() {
    return 51;
  }

  @override
  int autoLowHighBeamOnOffCmd() {
    return 47;
  }
}

class _V12CmdV2 extends _V12CmdV1 {
  @override
  int speedThrOfLowHighBeamSwitchCmd() {
    return 48;
  }

  @override
  int remainderRangeEstimateCmd() {
    return 63;
  }

  @override
  int speedingBrakingSensitivityCmd() {
    return 64;
  }

  @override
  int assistBalanceCmd() {
    return 65;
  }

  @override
  int speedingBrakingCmd() {
    return 66;
  }

  @override
  int headlightOnOffCmd() {
    return 80;
  }

  @override
  int playSoundItemCmd() {
    return 81;
  }

  @override
  int calibrateImuCmd() {
    return 82;
  }

  @override
  int disableChargeDangerAlertCmd() {
    return 83;
  }
}


class PublicV12CmdV2 extends _V12CmdV2 {

}